package com.vst.orm.search.jpa;

import java.io.Serializable;
import javax.persistence.Entity;

import com.vst.orm.search.Metadata;
import com.vst.orm.util.MetadataUtil;

public class JPAAnnotationMetadataUtil
  implements MetadataUtil
{
  public Metadata get(Class<?> klass)
  {
    return JPAAnnotationMetadata.getMetadata(klass);
  }
  
  public Metadata get(Class<?> rootEntityClass, String propertyPath)
  {
    Metadata md = get(rootEntityClass);
    if ((propertyPath == null) || (propertyPath.equals(""))) {
      return md;
    }
    for (String prop : propertyPath.split("\\."))
    {
      md = md.getPropertyType(prop);
      if (md == null) {
        throw new IllegalArgumentException("Property path '" + propertyPath + "' invalid for type " + rootEntityClass.getName());
      }
    }
    return md;
  }
  
  public Serializable getId(Object object)
  {
    Metadata md = get(object.getClass());
    return md.getIdValue(object);
  }
  
  public boolean isId(Class<?> rootClass, String propertyPath)
  {
    if ((propertyPath == null) || ("".equals(propertyPath))) {
      return false;
    }
    if ((propertyPath.equals("id")) || ((propertyPath.endsWith(".id")) && (get(rootClass, propertyPath.substring(0, propertyPath.length() - 3)).isEntity()))) {
      return true;
    }
    int pos = propertyPath.lastIndexOf(".");
    if (pos != -1)
    {
      Metadata parentType = get(rootClass, propertyPath.substring(0, pos));
      if (!parentType.isEntity()) {
        return false;
      }
      return propertyPath.substring(pos + 1).equals(parentType.getIdProperty());
    }
    return propertyPath.equals(get(rootClass).getIdProperty());
  }
  
  public <T> Class<T> getUnproxiedClass(Class<?> klass)
  {
    while (klass.getAnnotation(Entity.class) == null)
    {
      klass = klass.getSuperclass();
      if (Object.class.equals(klass)) {
        return null;
      }
    }
    return (Class<T>) klass;
  }
  
  public <T> Class<T> getUnproxiedClass(Object entity)
  {
    return getUnproxiedClass(entity.getClass());
  }
}

